package io.zcoder.innoway.activities;

import android.app.DatePickerDialog;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.DatePicker;
import android.widget.ImageView;

import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.fitness.Fitness;
import com.google.android.gms.fitness.data.DataPoint;
import com.google.android.gms.fitness.data.DataSet;
import com.google.android.gms.fitness.data.DataSource;
import com.google.android.gms.fitness.data.DataType;
import com.google.android.gms.fitness.data.Field;

import java.sql.Driver;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;

import butterknife.BindView;
import butterknife.BindViews;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.zcoder.innoway.R;
import io.zcoder.innoway.utils.Utils;
import io.zcoder.innoway.commons.Constants;
import io.zcoder.innoway.commons.PrefUtils;
import io.zcoder.innoway.models.Dashboard;
import io.zcoder.innoway.models.ResponseBase;
import io.zcoder.innoway.rest.RestClient;
import io.zcoder.innoway.widgets.TextViewCustom;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;

public class ManualEntryActivity extends BaseActivity implements View.OnTouchListener {

    @BindViews({R.id.value_1, R.id.value_2, R.id.value_3, R.id.value_4, R.id.value_5, R.id.value_6, R.id.value_7, R.id.value_8})
    TextViewCustom[] mValuesText;
    @BindViews({R.id.plus_1, R.id.plus_2, R.id.plus_3, R.id.plus_4, R.id.plus_5, R.id.plus_6, R.id.plus_7, R.id.plus_8})
    ImageView[] mPlusView;
    @BindViews({R.id.minus_1, R.id.minus_2, R.id.minus_3, R.id.minus_4, R.id.minus_5, R.id.minus_6, R.id.minus_7, R.id.minus_8})
    ImageView[] mMinusView;

    @BindView(R.id.common_cancel_left)
    TextViewCustom mCancel;
    @BindView(R.id.common_ok)
    TextViewCustom mOkCommon;
    @BindView(R.id.date_text)
    TextViewCustom mDateText;
    public static GoogleApiClient mClient = null;

    @OnClick(R.id.common_ok)
    void ok() {
        showProgress();
        RestClient.build(this, true).addEntry(mDashboard, new Callback<ResponseBase>() {
            @Override
            public void success(ResponseBase responseBase, Response response) {
                hideProgress();
                if (responseBase.getStatus_code() != 200) {
                    showAlert(getString(R.string.error), responseBase.getMessage());
                } else {
                    setResult(RESULT_OK);
                    finish();
                }
            }

            @Override
            public void failure(RetrofitError error) {
                hideProgress();
            }
        });
        saveGoogleFit(mDashboard);
    }

    void saveGoogleFit(Dashboard entry) {
        if (!mClient.isConnected()) return;
        // Set a start and end time for our data, using a start time of 1 hour before this moment.
        Calendar cal = Calendar.getInstance();
        Date now = new Date();
        cal.setTime(now);
        long endTime = cal.getTimeInMillis();
        cal.add(Calendar.HOUR_OF_DAY, -1);
        long startTime = cal.getTimeInMillis();

        // Create a data source
        DataSource dataSource = new DataSource.Builder()
                .setAppPackageName(this)
                .setDataType(DataType.TYPE_WEIGHT)
                .setStreamName("TAG" + " - step count")
                .setType(DataSource.TYPE_RAW)
                .build();

        DataSet dataSet = DataSet.create(dataSource);
        // For each data point, specify a start time, end time, and the data value -- in this case,
        // the number of new steps.
        DataPoint dataPoint = dataSet.createDataPoint()
                .setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS);
        dataPoint.getValue(Field.FIELD_WEIGHT).setFloat(entry.getWeight());
        dataSet.add(dataPoint);
        com.google.android.gms.common.api.Status insertStatus =
                Fitness.HistoryApi.insertData(mClient, dataSet)
                        .await(1, TimeUnit.MINUTES);

        // Before querying the data, check to see if the insertion succeeded.
        if (!insertStatus.isSuccess()) {
            Log.i("Google Fit", "There was a problem inserting the dataset.");
        }
    }

    @OnClick(R.id.btn_ok)
    void ok1() {
        ok();
    }

    @OnClick(R.id.common_cancel_left)
    void cancel() {
        finish();
    }

    @OnClick({R.id.plus_1, R.id.plus_2, R.id.plus_3, R.id.plus_4, R.id.plus_5, R.id.plus_6, R.id.plus_7, R.id.plus_8})
    void onPlus(View view) {
        plusView(view.getId());
    }

    @OnClick({R.id.minus_1, R.id.minus_2, R.id.minus_3, R.id.minus_4, R.id.minus_5, R.id.minus_6, R.id.minus_7, R.id.minus_8})
    void onMinus(View view) {
        minusViews(view.getId());
    }

    @OnClick(R.id.layout_date)
    void onDate() {
        Calendar calendar = Calendar.getInstance();
        new DatePickerDialog(this, dateSetListener, calendar
                .get(Calendar.YEAR), calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH)).show();
    }

    private DatePickerDialog.OnDateSetListener dateSetListener = new DatePickerDialog.OnDateSetListener() {
        @Override
        public void onDateSet(DatePicker view, int year, int monthOfYear,
                              int dayOfMonth) {
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.YEAR, year);
            calendar.set(Calendar.MONTH, monthOfYear);
            calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
            mDateText.setText(Utils.convertToString(calendar.getTime(), Utils.DATE_FORMAT_MMM_DD_YYYY));
            mDashboard.setSaved_time(Utils.convertToString(calendar.getTime(), Utils.DATE_FORMAT_YYYY_MM_DD_HH_MM_SS));
        }

    };

    private CountDownTimerCustom beginTimer = new CountDownTimerCustom(1500, 1000) {

        @Override
        public void onTick(long millisUntilFinished) {

        }

        @Override
        public void onFinish() {
            countTimer.startWith(getId());
        }
    };
    private CountDownTimerCustom countTimer = new CountDownTimerCustom(100000, 100) {

        @Override
        public void onTick(long millisUntilFinished) {
            plusView(getId());
            minusViews(getId());
        }

        @Override
        public void onFinish() {

        }
    };
    private Dashboard mDashboard;
    private int mWeightType;
    private String mPercent;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_manual_entry_activity);
        ButterKnife.bind(this);
        setTitle(getString(R.string.manual_entry));
        mCancel.setVisibility(View.VISIBLE);
        mOkCommon.setVisibility(View.VISIBLE);
        mDashboard = getIntent().getParcelableExtra(Constants.DASHBOARD_EXTRAS);
        mWeightType = getIntent().getIntExtra(Constants.WEIGHT_TYPE_EXTRAS, 0);
        if (mDashboard == null) {
            mDashboard = new Dashboard();
        }
        mDashboard.setId(PrefUtils.getInt(this, PrefUtils.PREF_PROFILE_ID));
        mPercent = getString(R.string.percent);
        for (int i = 0; i < mPlusView.length; i++) {
            mPlusView[i].setOnTouchListener(this);
            mMinusView[i].setOnTouchListener(this);
        }
        initViews();

        mClient = new GoogleApiClient.Builder(this).addApi(Fitness.HISTORY_API).build();
    }

    private void initViews() {
        Calendar calendar = Calendar.getInstance();
        mDateText.setText(Utils.convertToString(calendar.getTime(), Utils.DATE_FORMAT_MMM_DD_YYYY));
        mDashboard.setSaved_time(Utils.convertToString(calendar.getTime(), Utils.DATE_FORMAT_YYYY_MM_DD_HH_MM_SS));

        mValuesText[0].setText(String.format(mDashboard.getWeightWithUnit(mWeightType)));
        mValuesText[1].setText(String.format(mPercent, mDashboard.getBmi()));
        mValuesText[2].setText(String.format(mPercent, mDashboard.getBody_fat()));
        mValuesText[3].setText(String.format(mPercent, mDashboard.getMuscle()));
        mValuesText[4].setText(String.format(mPercent, mDashboard.getWater()));
        mValuesText[5].setText(String.format("%sKg", mDashboard.getBone_mass()));
        mValuesText[6].setText(String.format("%sKcal", mDashboard.getBmr()));
        mValuesText[7].setText(String.format(mPercent, mDashboard.getVisceral_fat()));
    }

    private void minusViews(int id) {
        switch (id) {
            case R.id.minus_1:
                mDashboard.setWeight(mDashboard.getWeight() - 0.5f);
                mValuesText[0].setText(String.format(mDashboard.getWeightWithUnit(mWeightType)));
                break;
            case R.id.minus_2:
                mDashboard.setBmi(mDashboard.getBmi() - 0.5f);
                mValuesText[1].setText(String.format(mPercent, mDashboard.getBmi()));
                break;
            case R.id.minus_3:
                mDashboard.setBody_fat(mDashboard.getBody_fat() - 0.5f);
                mValuesText[2].setText(String.format(mPercent, mDashboard.getBody_fat()));
                break;
            case R.id.minus_4:
                mDashboard.setMuscle(mDashboard.getMuscle() - 0.5f);
                mValuesText[3].setText(String.format(mPercent, mDashboard.getMuscle()));
                break;
            case R.id.minus_5:
                mDashboard.setWater(mDashboard.getWater() - 0.5f);
                mValuesText[4].setText(String.format(mPercent, mDashboard.getWater()));
                break;
            case R.id.minus_6:
                mDashboard.setBone_mass(mDashboard.getBone_mass() - 0.5f);
                mValuesText[5].setText(String.format("%sKg", mDashboard.getBone_mass()));
                break;
            case R.id.minus_7:
                mDashboard.setBmr(mDashboard.getBmr() - 0.5f);
                mValuesText[6].setText(String.format("%sKcal", mDashboard.getBmr()));
                break;
            case R.id.minus_8:
                mDashboard.setVisceral_fat(mDashboard.getVisceral_fat() - 0.5f);
                mValuesText[7].setText(String.format(mPercent, mDashboard.getVisceral_fat()));
                break;
        }
    }

    private void plusView(int id) {
        switch (id) {
            case R.id.plus_1:
                mDashboard.setWeight(mDashboard.getWeight() + 0.5f);
                mValuesText[0].setText(String.format(mDashboard.getWeightWithUnit(mWeightType)));
                break;
            case R.id.plus_2:
                mDashboard.setBmi(mDashboard.getBmi() + 0.5f);
                mValuesText[1].setText(String.format(mPercent, mDashboard.getBmi()));
                break;
            case R.id.plus_3:
                mDashboard.setBody_fat(mDashboard.getBody_fat() + 0.5f);
                mValuesText[2].setText(String.format(mPercent, mDashboard.getBody_fat()));
                break;
            case R.id.plus_4:
                mDashboard.setMuscle(mDashboard.getMuscle() + 0.5f);
                mValuesText[3].setText(String.format(mPercent, mDashboard.getMuscle()));
                break;
            case R.id.plus_5:
                mDashboard.setWater(mDashboard.getWater() + 0.5f);
                mValuesText[4].setText(String.format(mPercent, mDashboard.getWater()));
                break;
            case R.id.plus_6:
                mDashboard.setBone_mass(mDashboard.getBone_mass() + 0.5f);
                mValuesText[5].setText(String.format("%sKg", mDashboard.getBone_mass()));
                break;
            case R.id.plus_7:
                mDashboard.setBmr(mDashboard.getBmr() + 0.5f);
                mValuesText[6].setText(String.format("%sKcal", mDashboard.getBmr()));
                break;
            case R.id.plus_8:
                mDashboard.setVisceral_fat(mDashboard.getVisceral_fat() + 0.5f);
                mValuesText[7].setText(String.format(mPercent, mDashboard.getVisceral_fat()));
                break;

        }
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                beginTimer.startWith(v.getId());
                break;
            case MotionEvent.ACTION_UP:
                beginTimer.cancel();
                countTimer.cancel();
                break;
        }
        return false;
    }

    public class CountDownTimerCustom extends CountDownTimer {

        private int id;

        public CountDownTimerCustom(long millisInFuture, long countDownInterval) {
            super(millisInFuture, countDownInterval);
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public void startWith(int id) {
            this.id = id;
            start();
        }

        @Override
        public void onTick(long millisUntilFinished) {

        }

        @Override
        public void onFinish() {

        }
    }
}
